package it.lupo.core.gui.controller;

import it.lupo.core.LupoSession;
import it.lupo.core.LupoSession.TYPE;
import it.lupo.core.gui.MainApp;
import it.lupo.model.BarCode;
import it.lupo.model.User;
import it.lupo.model.service.ConfermentService;

import java.net.URL;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.ResourceBundle;

import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.Callback;

import org.apache.log4j.Logger;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;

import com.sun.rowset.internal.Row;

public class HomeController implements Initializable{ 
	
	public static final String FXML_FILE = "src/main/resources/home-type-selection.fxml";
	public static final String PLASTIC_BUTTON_SHORTCUT = "e";
	public static final String GLASS_BUTTON_SHORTCUT = "w";
	public static final String PAPER_BUTTON_SHORTCUT = "q";
	public static final String ALUMINIUM_BUTTON_SHORTCUT = "s";
	public static final String UNDIFFERENTIATED_BUTTON_SHORTCUT = "a";
	public static final String ORGANIC_BUTTON_SHORTCUT = "d";
	public static final String ORGANIC_BUTTON_SAVE="u";
	public static final String ORGANIC_BUTTON_EXIT="y";
	
	
	static final String DEFAULT_LABEL = "0.00";
	
	private static Logger logger = Logger.getLogger(HomeController.class);
	
	private static ConfermentService service = ConfermentService.getInstance();
	
	private DecimalFormat formatter = new DecimalFormat("0.00");

	private ObservableList<ConfermentTableRow> conferments = FXCollections.observableArrayList();
	
	private BarCode barcode = LupoSession.getCurrent().getBarcode();
	private User user = LupoSession.getCurrent().getUser();
	
	private int idx = 1;
	
//	@FXML
//	private Button plasticButton;
	
	@FXML
	private Label input_weight;
	
	@FXML
	private TableView<ConfermentTableRow> table;
	@FXML
	private TableColumn<ConfermentTableRow, String> idColumn;
	@FXML
	private TableColumn<ConfermentTableRow, String> typeColumn;
	@FXML
	private TableColumn<ConfermentTableRow, String> weightColumn;
	@FXML
	private TableColumn<ConfermentTableRow, String> objectColumn;

	
	@FXML
	private Label lbl_total;
	
	@FXML
	private Label lbl_operator;
	
	@FXML
	private Label lbl_barcode;
	
	
	private double total_value = 0.0;
	public void logout()
	{
		try {
			LupoSession.getCurrent().logout();
			MainApp.getInstance().change(LoginController.FXML_FILE);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void save()
	{	
		Action response = Dialogs.create()
		        .owner(null)
		        .title("Confirm Dialog")
		        .masthead("Look, a Confirm Dialog")
		        .message("Do you want to continue?")
		        .actions(Dialog.Actions.OK, Dialog.Actions.CANCEL)
		        .showConfirm();
		
		
		if (response == Dialog.Actions.OK) {
		service.create(barcode, user, conferments);
		total_value=0;
		lbl_total.setText(formatter.format(total_value));
		conferments.clear();	
		try {
			MainApp.getInstance().change(BarCodeController.FXML_FILE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		}
		else
		{
			//do nothing
		}
	}
	
	@FXML
	public void close()
	{
		try {
			MainApp.getInstance().change(BarCodeController.FXML_FILE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void keypress(KeyEvent event)
	{	 
		KeyCode code = event.getCode();
		
		System.out.println(event);
		
//		String currDouble ="";
//		if(!input_weight.getText().isEmpty())			
//			currDouble = input_weight.getText();
		String text = input_weight.getText();
		if(text.equals("0.00"))
			text = "";
		
		String character = event.getText().toLowerCase();
		if(code==KeyCode.BACK_SPACE && text.length()>0)
		{
			input_weight.setText(text.substring(0,text.length()-1));			
		}			
		else if(character.equals(ALUMINIUM_BUTTON_SHORTCUT))
			toAluminium();
		else if(character.equals(PAPER_BUTTON_SHORTCUT))
			toPaper();
		else if(character.equals(GLASS_BUTTON_SHORTCUT))
			toGlass();
		else if(character.equals(PLASTIC_BUTTON_SHORTCUT))
			toPlastic();
		else if(character.equals(UNDIFFERENTIATED_BUTTON_SHORTCUT))
			toUndifferentiated();
		else if(character.equals(ORGANIC_BUTTON_SHORTCUT))
			toOrganic();
		else if(character.equals(ORGANIC_BUTTON_SAVE))
			save();
		else if(character.equals(ORGANIC_BUTTON_EXIT))
			close();
		else		
		{
		try{
			
			String value  = text+event.getText();
			Double.parseDouble(value);//test if is a number		
			if(validate(value))
				input_weight.setText(String.valueOf(value));
			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
//		switch(code)
//		{
//			code.is
//		}
	}
	
	private boolean validate(String str)
	{
		if(str.isEmpty())
			return true;
		
		String split[] = str.split("\\.");
		System.out.println("STRING = "+str+" SPLIT "+Arrays.toString(split));
		boolean int_part = (split[0].length()<3);
		boolean decimal_part = split.length==1 || split[1].length()<3;
		return int_part&&decimal_part;
	}
	

	
	@FXML
	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
	
		
//		lbl_barcode.setText(barcode.getSurname()+" "+barcode.getName()+" - "+barcode.getCF()+" - "+barcode.getId());
		lbl_barcode.setText(barcode.getBarcode());
		lbl_operator.setText("Operatore : "+user.getUsername());
		conferments = FXCollections.observableArrayList();
		idColumn.setCellValueFactory(new PropertyValueFactory<ConfermentTableRow, String>("id"));
		typeColumn.setCellValueFactory(new PropertyValueFactory<ConfermentTableRow, String>("type"));
		weightColumn.setCellValueFactory(new PropertyValueFactory<ConfermentTableRow, String>("weight"));
		
		
		
		table.setItems(conferments);
		table.setRowFactory(
			    new Callback<TableView<ConfermentTableRow>, TableRow<ConfermentTableRow>>() {
			    	  @Override
			    	  public TableRow<ConfermentTableRow> call(TableView<ConfermentTableRow> tableView) {
			    	    final TableRow<ConfermentTableRow> row = new TableRow<>();
			    	    final ContextMenu rowMenu = new ContextMenu();
			    	    MenuItem removeItem = new MenuItem("Cancella");
			    	    removeItem.setOnAction(new EventHandler<ActionEvent>() {
			    	      @Override
			    	      public void handle(ActionEvent event) {
			    	        table.getItems().remove(row.getItem());
			    	        total_value-=row.getItem().getWeight();
			    	        lbl_total.setText(formatter.format(total_value));
			    	      }
			    	    });
			    	    rowMenu.getItems().addAll(removeItem);

			    	    // only display context menu for non-null items:
			    	    row.contextMenuProperty().bind(
			    	      Bindings.when(Bindings.isNotNull(row.itemProperty()))
			    	      .then(rowMenu)
			    	      .otherwise((ContextMenu)null));
			    	    return row;
			    	  }
			    	});
	}
	
	@FXML
	public void toPlastic()
	{
		try {
			logger.info("PLASTIC");									
			add(TYPE.PLASTIC, Double.parseDouble(input_weight.getText()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void toGlass()
	{
		try {
			logger.info("GLASS");					
			add(TYPE.GLASS, Double.parseDouble(input_weight.getText()));	
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void toUndifferentiated()
	{
		try {
			logger.info("UNDIFFERENTIATED");					
			add(TYPE.UNDIFFERENTIATED, Double.parseDouble(input_weight.getText()));		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void toOrganic()
	{
		try {
			logger.info("ORGANIC");					
			add(TYPE.ORGANIC, Double.parseDouble(input_weight.getText()));			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@FXML
	public void toAluminium()
	{
		try {
			logger.info("ALUMINIUM");					
			add(TYPE.ALUMINIUM, Double.parseDouble(input_weight.getText()));			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	
	@FXML
	public void toPaper()
	{
		try {
			logger.info("PAPER");	
			add(TYPE.PAPER, Double.parseDouble(input_weight.getText()));		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	
	
	
	
	public void add(TYPE type,double weight)
	{
		if(weight<=0)
			return;
		
		conferments.add(new ConfermentTableRow(idx++,type.toString(),weight));
		System.out.println(conferments.size());
		
		total_value+=weight;
		lbl_total.setText(formatter.format(total_value));
		resetLabel();
	}
	
	private void resetLabel()
	{
		input_weight.setText(DEFAULT_LABEL);
	}
	



}
